package com.icinema.server;

import java.util.ArrayList;
import java.util.List;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.icinema.client.CinemaService;
import com.icinema.client.Constants;
import com.icinema.client.Message;
import com.icinema.server.factories.EntityFactory;
import com.icinema.vo.Cinema;
import com.icinema.vo.CinemaSubscription;
import com.icinema.vo.CinemaSubscriptionDetail;
import com.icinema.vo.MovieShowing;
import com.icinema.vo.User;

public class CinemaServiceImpl  extends RemoteServiceServlet implements CinemaService {
	/**
	 * 
	 */
	private static final long serialVersionUID = 3270085058056134504L;
	DatastoreService datastore;
	public CinemaServiceImpl(){
		datastore = DatastoreServiceFactory.getDatastoreService();		
	}
	@Override
	public String addCinema(Cinema cinema) {
		Entity cinemaEntity = new Entity(Cinema.class.getSimpleName());
		cinemaEntity.setProperty("name",cinema.getName());
		cinemaEntity.setProperty("manager",cinema.getManager());
		cinemaEntity.setProperty("address",cinema.getAddress());
		cinemaEntity.setProperty("phone",cinema.getPhone());
		cinemaEntity.setProperty("seatCapacity",cinema.getSeatCapacity());
		datastore.put(cinemaEntity);
		return KeyFactory.keyToString(cinemaEntity.getKey());	
	}
	
	@Override
	public void delete(String key) {
		datastore.delete(KeyFactory.stringToKey(key));
	}
	
	@Override
	public Message deleteCinema(String key) {
		Query query = new Query(MovieShowing.class.getSimpleName());
		query.addFilter("cinemaId", FilterOperator.EQUAL, key);
		Message msg = new Message();
		 if(datastore.prepare(query).asIterable(FetchOptions.Builder.withDefaults()).iterator().hasNext()){
			 msg.setErr_msg("This Cinema is used in the showing list.Cannot Delete");
			 return msg;
		 }
		 delete(key);
		 return msg;		
	}
	@Override
	public List<Cinema> getCinemas() {
		Query query = new Query(Cinema.class.getSimpleName());
		//query.addFilter("photoKey", FilterOperator.EQUAL, image.getKey());
		
		List<Cinema> results = new ArrayList<Cinema>();
		
		for(Entity entity : datastore.prepare(query).asIterable(FetchOptions.Builder.withDefaults())) {
			Cinema cinema = new Cinema();
			cinema.setName((String)entity.getProperty("name"));
			cinema.setManager((String)entity.getProperty("manager"));
			cinema.setAddress((String)entity.getProperty("address"));
			cinema.setPhone((String)entity.getProperty("phone"));
			cinema.setSeatCapacity((Long)entity.getProperty("seatCapacity"));
			cinema.setId(KeyFactory.keyToString(entity.getKey()));
			results.add(cinema);
		}
		
		return results;
		
	}
	public void addCinemaSubscription(CinemaSubscription subScription){
		String userId = (String)getThreadLocalRequest().getSession().getAttribute(Constants.SESSION_USER_ID);
		subScription.setUserId(userId);
		Entity cineSubcriptEntity = new Entity(CinemaSubscription.class.getSimpleName());
		cineSubcriptEntity.setProperty("userId", subScription.getUserId());
		cineSubcriptEntity.setProperty("cinemaId", subScription.getCinemaId());
		datastore.put(cineSubcriptEntity);
	}
	public List<CinemaSubscriptionDetail> getCinemaSubscriptions(){
		String userId = "";
		userId = (String)getThreadLocalRequest().getSession().getAttribute(Constants.SESSION_USER_ID);	
		Query query = new Query(CinemaSubscription.class.getSimpleName());
		query.addFilter("userId", FilterOperator.EQUAL, userId);
		List<CinemaSubscription> results = new ArrayList<CinemaSubscription>();
		for(Entity entity:datastore.prepare(query).asIterable(FetchOptions.Builder.withDefaults())){
			CinemaSubscription subscript = new CinemaSubscription();
			subscript.setCreatedDate((String)entity.getProperty("createdDate"));
			subscript.setUserId((String)entity.getProperty("userId"));
			subscript.setCinemaId((String) entity.getProperty("cinemaId"));
			subscript.setId(KeyFactory.keyToString(entity.getKey()));
			results.add(subscript);
		}
		List<CinemaSubscriptionDetail> detailList = new ArrayList<CinemaSubscriptionDetail>();
		for(CinemaSubscription sub:results){
			CinemaSubscriptionDetail detail = new CinemaSubscriptionDetail();
			detail.setCinemaSubscription(sub);
			try {
				Entity userEntity = datastore.get(KeyFactory.stringToKey(sub.getUserId()));
				Entity cinemaEntity = datastore.get(KeyFactory.stringToKey(sub.getCinemaId()));
				detail.setCinema(fromCinemaEntity(cinemaEntity));
				detail.setUser(fromUserEntity(userEntity));
				detailList.add(detail);
			} catch (EntityNotFoundException e) {
				e.printStackTrace();
			}
		}
		return detailList;
	}
	
	
	
	public User fromUserEntity(Entity entity){
		return new EntityFactory<User>().toUser(entity);
	}
	
	public Cinema fromCinemaEntity(Entity entity){
		return new EntityFactory<Cinema>().toCinema(entity);
	}		
}
